GDK W32: Ensure that selection request is processed
authorРуслан Ижбулатов <lrn1986@gmail.com>
Mon, 18 Sep 2017 16:49:11 +0000 (16:49 +0000)
committerРуслан Ижбулатов <lrn1986@gmail.com>
Sat, 25 Nov 2017 15:44:43 +0000 (15:44 +0000)
To do that, run the message loop for one second or until the side-effect
of running the selection request handler is achieved (as opposed to
running it until the event is no longer queued).

The disavantage of this method is that if the event handling is
somehow missed (due to a variety of reasons - after all, it's not
a straight path from an event being queued to property_change()
being called), this will loop for one second. Since we do process
events during that time, this will not hang the application, but
might still restrict some of the functionality.

https://bugzilla.gnome.org/show_bug.cgi?id=786509

gdk/win32/gdkdnd-win32.c
gdk/win32/gdkselection-win32.c

index c14ca2e4de75d2ff9b8c3ac2510cd021177e0b09..0583c613d0f8e64341ec135c89e1c68eb6232438 100644 (file)
@@ -1030,6 +1030,7 @@ idataobject_getdata (LPDATAOBJECT This,
   GdkEvent e;
   gint i;
   GdkAtom target;
+  gint64 loopend;
 
   GDK_NOTE (DND, g_print ("idataobject_getdata %p %s ",
                          This, _gdk_win32_cf_to_string (pFormatEtc->cfFormat)));
@@ -1093,10 +1094,12 @@ idataobject_getdata (LPDATAOBJECT This,
 
   gdk_event_put (&e);
 
-  process_pending_events (gdk_device_get_display (gdk_drag_context_get_device (ctx->context)));
+  /* Don't hold up longer than one second */
+  loopend = g_get_monotonic_time () + 1000000000;
 
-  win32_sel->property_change_format = 0;
-  win32_sel->property_change_data = 0;
+  while (win32_sel->property_change_data != 0 &&
+         g_get_monotonic_time () < loopend)
+    process_pending_events (gdk_device_get_display (gdk_drag_context_get_device (ctx->context)));
 
   if (pMedium->hGlobal == NULL) {
     GDK_NOTE (DND, g_print (" E_UNEXPECTED\n"));
index 86ff0d7090be1001859bdb3aee522d0804c81015..5fd02a698e3af473ace1ee5304cb8af6d1cea29c 100644 (file)
@@ -2393,6 +2393,9 @@ _gdk_win32_selection_property_change (GdkWin32Selection *win32_sel,
 
           g_free (set_data);
         }
+
+      win32_sel->property_change_format = 0;
+      win32_sel->property_change_data = 0;
     }
   else
     {